package org.yeasy.report.constant;

import lombok.Data;
import org.yeasy.report.enums.ColumnKeepStrategyEnum;

/**
 * The type Column keep strategy.列保持合并策略
 * 仅对部分方法生效
 *
 * @param <T> the type parameter
 * @author yangyishe
 * @date 2022年09月13日 09:12
 */
@Data
public class KeepStrategy<T> {
    /**
     * The constant KEEP_FIRST.
     */
    public static final Integer FIRST_ALWAYS= ColumnKeepStrategyEnum.FIRST_ALWAYS.getType();
    /**
     * The constant KEEP_FIRST_PRIOR.
     */
    public static final Integer FIRST_PRIOR= ColumnKeepStrategyEnum.FIRST_PRIOR.getType();
    /**
     * The constant KEEP_LAST_ALWAYS.
     */
    public static final Integer LAST_ALWAYS= ColumnKeepStrategyEnum.LAST_ALWAYS.getType();
    /**
     * The constant KEEP_LAST.
     */
    public static final Integer LAST_PRIOR=ColumnKeepStrategyEnum.LAST_PRIOR.getType();
    /**
     * The constant KEEP_NULL.
     */
    public static final Integer DEFAULT=ColumnKeepStrategyEnum.DEFAULT.getType();


    private Integer strategy;

    private T defaultValue;


    /**
     * Get instance keep strategy.
     *
     * @param <T>      the type parameter
     * @param strategy the strategy
     * @return the keep strategy
     * @author yangyishe
     * @date 2022年09月13日 15:04
     */
    public static<T> KeepStrategy<T> getInstance(Integer strategy){
        KeepStrategy<T> keepStrategy=new KeepStrategy<>();
        keepStrategy.setStrategy(strategy);
        return keepStrategy;
    }

    /**
     * Get instance keep strategy.
     *
     * @param <T>          the type parameter
     * @param strategy     the strategy
     * @param defaultValue the default value
     * @return the keep strategy
     * @author yangyishe
     * @date 2022年09月13日 15:04
     */
    public static<T> KeepStrategy<T> getInstance(Integer strategy,T defaultValue){
        KeepStrategy<T> keepStrategy=new KeepStrategy<>();
        keepStrategy.setStrategy(strategy);
        keepStrategy.setDefaultValue(defaultValue);
        return keepStrategy;
    }

    /**
     * Merge value t.
     *
     * @param preVal  the pre val
     * @param nextVal the next val
     * @return the t
     * @author yangyishe
     * @date 2022年09月13日 09:12
     */
    public T mergeValue(T preVal,T nextVal){
        ColumnKeepStrategyEnum columnKeepStrategyEnum=this.strategy!=null
                ?ColumnKeepStrategyEnum.type2Enum(this.strategy)
                :ColumnKeepStrategyEnum.FIRST_PRIOR;
        T resultVal;
        switch (columnKeepStrategyEnum){
            case FIRST_ALWAYS:
                resultVal=preVal;
                break;
            case FIRST_PRIOR:
                resultVal= preVal!=null?preVal:nextVal;
                break;
            case LAST_ALWAYS:
                resultVal= nextVal;
                break;
            case LAST_PRIOR:
                resultVal= nextVal!=null?nextVal:preVal;
                break;
            case DEFAULT:
                resultVal= this.defaultValue;
                break;
            default:
                resultVal= preVal;
                break;
        }
        if(resultVal==null){
            resultVal=this.defaultValue;
        }
        return resultVal;
    }

}
